www.gusucode.com > matlab编程NSCT分解 图像融合 各个融合指标评价体系 分解源码程序 > matlab编程NSCT分解 图像融合 各个融合指标评价体系 分解源码程序/NSCT/histmatch.m

    function varargout = histmatch(image,matchhist,mapl)
%    HISTMATCH    直方图规定化函数
%      matchhist为规定直方图,规定图像的灰度级N<=M
%      没有该参数输入,默认为执行直翻图均衡化
%      mapl只有有matchhist参数时才具有意义,为映射规则
%      可以取值为SML和GML,默认为SML
%      无输出默认输出原始图像、原始直方图、规定图像、规定图像直方图
%    $Author: lskyp    $Date: 2009.08.18
error(nargchk(1,3,nargin));
% 没有规定直方图输入,即输入参数只有一个,执行直方图均衡化
if nargin == 1
    if nargout == 0
        histeq_my(image);
    else
        [imageeq,grayx,histeq,hist] = histeq_my(image);
        varargout = {imageeq,grayx,histeq,hist};
    end
else
    if nargin == 2
        mapl = 'GML';
    end
    if ~ (strcmp(mapl,'GML') || strcmp(mapl,'SML'))
        error('错误的映射规则')
    end
    if ndims(matchhist) > 2 || (ndims(matchhist) == 2 && (size(matchhist,1) ...
            >1 && size(matchhist,2) > 1))
        error('错误的规定直方图,规定直方图需为向量')
    end
    matchhist = matchhist(:);
    matchhist = matchhist';
    N = length(matchhist);
    M = double(intmax(class(image))) + 1;
    if N > M
        error('错误的规定直方图,规定直方图灰度级需<=原始灰度级')
    elseif N < M % 可以视为>N的灰度部分置零
        matchhist = [matchhist zeros(1,M - N)];
    end
    [hist,grayx] = imhist_my(image);
    % 归一化
    histn = hist/numel(image);
    % 原始直方图的累积直方图
    histc = cumsum(histn);
    % 规定直方图的累积直方图
    matchhistc = cumsum(matchhist);
    % 映射的实现,Ref. 章毓晋. 图像工程(上册)——图像处理
    tk = zeros(1,M); % 映射关系hist-->tk
    if strcmp(mapl,'SML')
        tk(1) = 1; % 2009.08.19增加,为下一步修改准备
        linit = 2;
        kinit = 0;
        for k = 1:M
            if histc(k) == 0
                kinit = kinit + 1;
            else
                break;
            end
        end
        
        % 标记为SML为零的位置
        indis0 = zeros(1,N);
        
        for k = kinit:M
            mappingL = zeros(size(matchhist));
            % 2009.08.19为节省运算量而修改
            for l = linit:N % 2009.08.19修改,规定直方图从上一次最小处计算,节省运算时间
                if matchhistc(l) == matchhistc(l - 1);
                    continue;
                end
                mappingL(l) = abs(histc(k) - matchhistc(l));
                if mappingL(l) == 0
                    indis0(linit) = 1;
                end
            end
            mappingL(N) = abs(histc(k) - matchhistc(N));
            indtemp1 = find(mappingL == 0);
            indtemp2 = find(indis0 == 1);
            mappingL(setdiff(indtemp1,indtemp2)) = inf;
            [minmap,tk(k)] = min(mappingL(linit:N));
            linit = tk(k) + linit - 1;
            tk(k) = linit;
            for k = 1:kinit - 1
                tk(k) = tk(kinit);
            end
        end
    else % 组映射规则GML
        % 2009.08.19 Ref. 章毓晋. 《图像工程》(上册) P96,图4.4.8 GML映射计算图
        graymarker = 1;
        for k = 1:N
            if matchhistc(k) == 0;
                graymarker = graymarker + 1;
            else
                break;
            end
        end
        linit = graymarker;
        tk(1) = linit;
        tkcnt = 2;
        
        % 标记为GML为零的位置
        indis0 = zeros(1,N);
        
        for l = linit:N
            mappingL = zeros(1,M);
            if matchhistc(l) == matchhistc(l - 1);
                continue;
            end
            for k = 1:M - 1
                if histc(k) == histc(k + 1) % 跳过原始累积直方图有相同值的元素
                    % 如果不跳过,那么再寻找最小值时,会有一系列最小值,而MATLAB
                    % 只找到第一个最小值的位置,但是需要的应该是最后一个,跳过后,
                    % mappingL矩阵中会出现0值,那么寻找最小值会误算,因此,在下面
                    % 的语句中有一句将这些零值赋为最大inf
                    continue;
                end
                mappingL(k) = abs(matchhistc(l) - histc(k)); % GML规则
                if mappingL(k) == 0
                    indis0(k) = 0;
                end
            end
            mappingL(M) = abs(matchhistc(l) - histc(M));
            indtemp1 = find(mappingL == 0);
            indtemp2 = find(indis0 == 1);
            mappingL(setdiff(indtemp1,indtemp2)) = inf;
            [minmap,minind] = min(mappingL);
            for pp = tkcnt:minind
                tk(pp) = l; % 建立灰度映射矩阵
            end
            tkcnt = minind + 1;
        end
    end
    if N < M
        for k = N:M
            tk(k) = N;
        end
    end
    histm = zeros(1,N);
    for k = 1:M
        histm(tk(k)) = histm(tk(k)) + hist(k);
    end
    tk = tk - 1; % 方便灰度值的计算
    % 图像的规定化
    imagematch = zeros(size(image));
    for p = 1:size(image,1)
        for q = 1:size(image,2)
            ind = image(p,q) + 1;
            imagematch(p,q) = tk(ind);
        end
    end
    eval(['imagematch = ' class(image) '(imagematch);'])
    graymatch = 0:length(histm) - 1;
    % 输出
    if nargout == 0
        subplot(221)
        imshow(image)
        title('原始图像')
        subplot(222)
        imshow(imagematch)
        title('直方图规定化后图像')
        subplot(223)
        stem(grayx,hist,'Marker','none')
        xlim([0 max(grayx)]);
        xlabel('灰度值')
        ylabel('统计个数');
        title('原始直方图')
        subplot(224)
        stem(graymatch,histm,'Marker','none')
        xlim([0 max(graymatch)]);
        xlabel('灰度值')
        ylabel('统计个数');
        title(['规定化后直方图' mapl])
    else
        varargout = {imagematch,graymatch,histm,grayx,hist};
    end
end